import * as React from 'react';

import immutableObject from '../../common/immutableObject';
import views from '../../views';
import {IView} from '../../types/IView';
import {IAttr} from '../../types/IAttr';

import AttributePaneItem from './AttributePaneItem';
import StylePane from './StylePane';

import './AttributePane.css';

export interface AttributePaneProps {
  designId: string;
  selectedView: IView;
}

interface PseudoClassSelection {
  [pseudoClass: string]: boolean;
}

export interface AttributePaneState {
  isStyleExtExpanded: boolean;
  selectedPseudoClass: PseudoClassSelection;
}

class AttributePane extends React.Component<AttributePaneProps, AttributePaneState> {
  private pseudoClasses: string[] = [':active', ':hover', ':focus', ':visited'];

  constructor(props: AttributePaneProps) {
    super(props);

    this.state = {
      isStyleExtExpanded: false,
      selectedPseudoClass: {}
    };
  }

  render(): JSX.Element | null {
    const {selectedView} = this.props;
    const viewObject = views[selectedView.viewType];
    const {attrs} = viewObject;

    const styleTitleClass = `Attribute-title ${this.state.isStyleExtExpanded ? 'expanded' : ''}`;
    return (
      <div className="Attribute">
        <div className="Attribute-title">属性设置</div>
        <div className="Attribute-items">
          {(attrs || []).map(attribute => this.renderAttribute(attribute))}
        </div>
        <div className={styleTitleClass}>
          <span>样式设置</span>
          <span className="Attribute-title-ext-button" onClick={this.toggleStyleExt}>:hov</span>
          <div className="Attribute-title-ext-pane">
            {this.pseudoClasses.map(pseudoClass => this.renderPseudo(pseudoClass))}
          </div>
        </div>
        <StylePane {...this.props} target={this.state.selectedPseudoClass[':hover'] ? 'hoverStyle' : 'style'}/>
      </div>
    );
  }

  componentWillReceiveProps(nextProps: AttributePaneProps) {
    if (nextProps.selectedView.id === this.props.selectedView.id) {
      return;
    }

    // 当选择了另外一个组件时, 要取消那些伪类的选择状态
    this.setState({...this.state, selectedPseudoClass: {}});
  }

  private renderAttribute(attribute: IAttr): JSX.Element | null {
    return (
      <AttributePaneItem key={attribute.name} {...this.props} attribute={attribute} target="attrVals"/>
    );
  }

  private renderPseudo(pseudoClass: string): JSX.Element | null {
    const props: React.InputHTMLAttributes<HTMLInputElement> = {
      name: 'pseudo',
      value: pseudoClass,
      checked: this.state.selectedPseudoClass[pseudoClass] || false,
      onChange: this.togglePseudoSelection
    };
    return (
      <label key={pseudoClass}>
        <input type="checkbox" {...props}/>
        <span>{pseudoClass}</span>
      </label>
    );
  }

  private toggleStyleExt = () => {
    this.setState({...this.state, isStyleExtExpanded: !this.state.isStyleExtExpanded});
  }

  private togglePseudoSelection = (event: React.ChangeEvent<HTMLInputElement>) => {
    const pseudoClass = event.target.value;
    const newSelection = immutableObject.set(this.state.selectedPseudoClass, pseudoClass, event.target.checked);
    this.setState({...this.state, selectedPseudoClass: newSelection});
  }
}

export default AttributePane;
